package com.gitee.grower.core.ui

import com.gitee.grower.ItemGrower
import com.gitee.grower.ItemGrowerAPI
import com.gitee.grower.ItemGrowerAPI.countItem
import com.gitee.grower.ItemGrowerAPI.growLevel
import com.gitee.grower.api.event.PlayerItemModifyGrowEvents
import com.gitee.grower.api.event.PlayerItemModifyGrowEvents.*
import com.gitee.grower.core.kether.playKether
import com.gitee.grower.core.kether.toKetherDouble
import com.gitee.grower.core.kether.toKetherFunction
import com.gitee.grower.core.kether.toKetherInt
import com.gitee.grower.core.scheme.Item
import com.gitee.grower.core.scheme.Operation
import org.bukkit.Material
import org.bukkit.entity.Player
import org.bukkit.inventory.ItemStack
import taboolib.common.util.random
import taboolib.common.util.replaceWithOrder
import taboolib.library.configuration.ConfigurationSection
import taboolib.library.xseries.XMaterial
import taboolib.library.xseries.getItemStack
import taboolib.module.nms.getName
import taboolib.module.ui.openMenu
import taboolib.module.ui.type.Basic
import taboolib.module.ui.type.Linked
import taboolib.platform.compat.depositBalance
import taboolib.platform.compat.getBalance
import taboolib.platform.util.*

class LogicUI(val viewer: Player,val item: ItemStack) {

    companion object {

        val conf : ConfigurationSection
            get() = ItemGrower.config.getConfigurationSection("ui")!!

        val title: String
            get() = conf.getString("title","UI")!!

        val rows: Int
            get() = conf.getInt("rows",6)

        val mainSlot: Int
            get() = conf.getInt("main-slot")

        val itemSlot: List<Int>
            get() = conf.getIntegerList("item-slots")

        val fortuneSlot: Int
            get() = conf.getInt("item-slot")

        val perfectSlot: Int
            get() = conf.getInt("perfect-slot")

        val submit: ConfigurationSection
            get() = conf.getConfigurationSection("submit")!!

        val submitSlot : Int
            get() = submit.getInt("slot")

    }

    fun Item.name() : String {
        return if (this is Item.Default) {
            this.id
        } else {
            (this as Item.Condition).name
        }
    }

    fun checkCondition() {

    }

    fun open() {
        if (item.isAir()) return

        val scheme = ItemGrowerAPI.getScheme(viewer, item)

        if (scheme == null) {
            viewer.sendLang("item-un-grow-scheme",item.getName())
            return
        }

        val structure = ItemGrowerAPI.getStructure(viewer, item, scheme)
        if (structure == null) {
            viewer.sendLang("item-un-grow-structure",item.getName())
            return
        }

        viewer.openMenu<Linked<Item>>(title) {
            menuLocked(false)
            rows(rows)
            slots(itemSlot)
            elements { structure.items }

            onGenerate { player, element, index, slot -> buildItem(element.buildIcon(player)) {
                val toKetherInt = toKetherInt(player, element.amountScript, item)
                this.name += ItemGrower.appendAmount?.replaceWithOrder(element.countItem(player), toKetherInt) ?: ""
                this.amount = toKetherInt
            } }

            set(mainSlot,item) {
                this.isCancelled = true
            }

            set(submitSlot, conf.getItemStack(submit.name)!!) {
                this.isCancelled = true

                // 检索祈福魔咒 保护魔咒
                val inferFortune = Infer.InferFortune(this.inventory.getItem(fortuneSlot))
                if (inferFortune.isValid && !inferFortune.match) {
                    viewer.sendLang("fortune-not-match",inferFortune.item?.getName() ?: "__null__")
                    return@set
                }
                val inferPerfect = Infer.InferPerfect(this.inventory.getItem(perfectSlot))
                if (inferPerfect.isValid && !inferPerfect.match) {
                    viewer.sendLang("perfect-not-match",inferFortune.item?.getName() ?: "__null__")
                    return@set
                }

                // Vault 金币检索
                if (viewer.getBalance() < structure.gold) {
                    viewer.sendLang("player-gold-lack",structure.gold - viewer.getBalance())
                    return@set
                }

                // 材料检索
                val matchItem = ItemGrowerAPI.checkMisMatchItem(viewer, item, scheme, structure)
                if (matchItem.isNotEmpty()) {
                    matchItem.forEach { viewer.sendLang("item-not-match",it.name()) }
                    return@set
                }

                val growPre = Pre(viewer, item, scheme, structure, toKetherDouble(viewer, structure.chance, item))

                if (!growPre.call()) return@set

                inferFortune.takeItem(1)
                inferPerfect.takeItem(1)
                viewer.depositBalance(structure.gold)
                // 概率为结构本身概率 + 祈福魔咒概率


                if (random(growPre.chance)) {

                    if (Succeed(viewer, item, scheme, structure).call()) {
                        ItemGrowerAPI.modifyItemGrow(viewer,item,scheme, structure,Operation.INCREASE)
                        viewer.sendLang("item-grow-success",item.getName(),"+${item.growLevel()}")
                        playKether(viewer,structure.successAction,item)
                    }

                }
                // 失败逻辑块
                else {

                    // 检索失败事件
                    if (Failed(viewer,item,scheme,structure).call()) {
                        viewer.sendLang("item-grow-fail",item.getName(),"+${item.growLevel() + 1}")
                        playKether(viewer,structure.failAction,item)

                        val degradedPre = DegradedPre(viewer,item,scheme,structure,toKetherDouble(viewer,structure.degradedChance,item) - inferFortune.get(viewer, item))

                        // 该阶段开启了掉级 并且成功掉级
                        if (structure.isDegraded && degradedPre.call()) {
                            if (random(degradedPre.chance)) {
                                if (DegradedPost(viewer,item,scheme,structure).call()) {
                                    ItemGrowerAPI.modifyItemGrow(viewer,item,scheme, structure,Operation.DECREASE)
                                    viewer.sendLang("item-grow-degraded",item.getName())
                                    playKether(viewer,structure.degradedAction,item)
                                }
                            } else if (inferFortune.match) {
                                viewer.sendLang("item-grow-degrade-perfect0",item.getName(),inferFortune.item!!.getName())
                                playKether(viewer,structure.degradedPerfectAction,item)
                            }


                        }


                        val negativePre = NegativePre(viewer,item,scheme,structure,toKetherDouble(viewer,structure.negativeChance,item) - inferPerfect.get(viewer,item))

                        // 该阶段开启了负面buff 并且成功给予负面buff
                        // 负面buff计算公式 原生+保护魔咒
                        if (structure.isNegative && structure.negativeLore.isNotEmpty() && negativePre.call()) {
                            if (random(negativePre.chance)) {
                                val negativeString = toKetherFunction(viewer,structure.negativeLore.random(),item)
                                if (NegativePost(viewer,item,scheme,structure,negativeString).call()) {
                                    ItemGrowerAPI.modifyNegativeItem(viewer,item,scheme,structure,negativeString)
                                    viewer.sendLang("item-grow-negative",item.getName(),negativeString)
                                    playKether(viewer,structure.negativeAction,item)
                                }
                            } else if (inferPerfect.match) {
                                viewer.sendLang("item-grow-negative-perfect0",item.getName(),inferPerfect.item!!.getName())
                                playKether(viewer,structure.negativePerfectAction,item)
                            }
                        }
                    }

                }
                Post(viewer,item,scheme, structure).call()
                // 重新打开界面重新检索
                open()
            }

            onClose { e ->
                e.inventory.getItem(fortuneSlot)?.let {
                    viewer.giveItem(it)
                    e.inventory.setItem(fortuneSlot,null)
                }

                e.inventory.getItem(perfectSlot)?.let {
                    viewer.giveItem(it)
                    e.inventory.setItem(perfectSlot,null)
                }
            }

            conf.getKeys(false).forEach {
                if (it.startsWith("_")) {
                    conf.getIntegerList("slots").forEach { slot ->
                        set(slot, conf.getItemStack(it)!!) {
                            this.isCancelled = true
                        }
                    }
                }
            }

            onClick { event, element ->
                event.isCancelled = true
            }

        }
    }

}